在 ${linux}/Documentation/arch
裡面有 5 篇文件,前面這幾天,大概都會是從這幾篇文件著墨;昨天的第 1 篇是描述 riscv-linux 的維護守則
,今天來看的是,Boot image header in RISC-V Linux
!描述的是一個 RISC-V 啟動影像檔,該要包含什麼樣的標頭,才可以被辨識為正確的啟動影像檔。
============================
RISC-V Linux 的啟動影像檔標頭
============================
:Author: Atish Patra <atish.patra@wdc.com>
:Date: 20 May 2019
這份文件僅描述 RISC-V Linux 啟動影像檔標頭的詳細訊息。
待完成:
寫一份完整的啟動流程指南。
解壓縮後的 Linux 核心影像檔中會含有以下 64 位元組的標頭::
u32 code0; /* 可執行程式碼 */
u32 code1; /* 可執行程式碼 */
u64 text_offset; /* 載入影像的偏移量 */
u64 image_size; /* 有效影像大小,小端序 */
u64 flags; /* 核心旗標,小端序 */
u32 version; /* 標頭版本 */
u32 res1 = 0; /* 保留 */
u64 res2 = 0; /* 保留 */
u64 magic = 0x5643534952; /* 魔術數字,小端序,"RISCV" */
u32 magic2 = 0x05435352; /* 魔術數字 2,小端序,"RSC\x05" */
u32 res3; /* 保留 PE COFF 的偏移量 */
這種標頭格式是深受 ARM64 標頭的影響並且相容於 PE/COFF 標頭。
因此,將來可以將 ARM64 和 RISC-V 標頭合併為一個通用標頭。
註
==
- 將來,這個標頭還可用來支援 RISC-V 的 EFI 模擬實作。 EFI 規範需要核心影像開頭的 PE/COFF 影像標頭,以便將其視作 EFI 應用程式來運行。為了支援 EFI 模擬,code0 應替換為 "MZ" 魔術字串,res3(偏移量 0x3c)應指向 PE/COFF 標頭的其餘部分。
- 版本欄位標示的是版本號
========== =====
位元 0:15 小版號
位元 16:31 大版號
========== =====
這樣可以保證新、舊版本間的相容性。
目前的版本被定義為 0.2。
- 自 0.2 版後,"magic" 欄位已不適用。在未來的版本中,它可能會被刪除。這本來應該和 ARM64 標頭 "magic" 欄位相符,但不幸的是沒有。 "magic 2" 欄位是用來替換 "magic" 的,並且與 ARM64 標頭相符。
- 在目前的標頭中,旗標欄位僅只有一個欄位。
====== ===============================================
位元 0 核心的位元組順序。 小端序,則為 1;大端序,則為 0。
====== ===============================================
- 啟動載入程式會需要核心影像檔案的大小資訊,否則啟動程序將會失敗。
booti 的使用方式: $ booti <kernel image addr> - <fdt addr>
/* ${uboot}/arch/riscv/lib/image.c */
int booti_setup(ulong image, ulong *relocated_addr, ulong *size,
bool force_reloc)
{
struct linux_image_h *lhdr;
lhdr = (struct linux_image_h *)map_sysmem(image, 0); // booti 指令中 kernel image 的 addr
if (lhdr->magic != LINUX_RISCV_IMAGE_MAGIC) { // 比對 magic 2 的欄位
puts("Bad Linux RISCV Image magic!\n");
return -EINVAL;
}
if (lhdr->image_size == 0) { // 確認 image_size 不為零
puts("Image lacks image_size field, error!\n");
return -EINVAL;
}
*size = lhdr->image_size;
...
}
${linux}/arch/riscv/kernel/head.S
中,把 Kernel Image 的 header 加上去的__HEAD /* MACRO --> .head.text */
ENTRY(_start)
/*
* Image header expected by Linux boot-loaders. The image header data
* structure is described in asm/image.h.
* Do not modify it without modifying the structure and all bootloaders
* that expects this header format!!
*/
/* jump to start kernel */
j _start_kernel /* 可執行程式碼 */
/* reserved */
.word 0 /* 可執行程式碼 */
.balign 8
#if __riscv_xlen == 64
/* Image load offset(2MB) from start of RAM */
.dword 0x200000 /* 載入影像的偏移量 */
#else
/* Image load offset(4MB) from start of RAM */
.dword 0x400000 /* 載入影像的偏移量 */
#endif
/* Effective size of kernel image */
.dword _end - _start /* 有效影像大小,小端序 */
.dword __HEAD_FLAGS /* 核心旗標,小端序 */
.word RISCV_HEADER_VERSION /* 標頭版本 */
.word 0 /* 保留 */
.dword 0 /* 保留 */
.ascii RISCV_IMAGE_MAGIC /* 魔術數字,小端序,"RISCV" */
.balign 4
.ascii RISCV_IMAGE_MAGIC2 /* 魔術數字 2,小端序,"RSC\x05" */
.word 0 /* 保留 PE COFF 的偏移量 */
xxd
、hexdump
等工具來檢視$ xxd ${linux}/arch/riscv/boot/Image |less
0000000: 6f10 0000 0000 0000 0000 2000 0000 0000 o......... .....
0000010: 3c30 7701 0000 0000 0000 0000 0000 0000 <0w.............
0000020: 0200 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 5249 5343 5600 0000 5253 4305 0000 0000 RISCV...RSC.....
...
不免俗地來送個 patch 吧!
$ git send-email --to corbet@lwn.net \
--to src.res@email.cn \
--to linux-kernel@vger.kernel.org \
--to linux-doc@vger.kernel.org \
--to linux-doc-tw-discuss@lists.sourceforge.net \
--cc ycliang@cs.nctu.edu.tw \
--cc ycliang@andestech.com \
0001-docs-zh_TW-Add-translation-for-riscv-boot-image-head.patch
原來持續的 output 會這麼累啊,才寫 2 篇文章,就筋疲力盡的感覺~XDD
感謝各位收看,讓我重整旗鼓,我們明日再戰!